
import { componentMap } from "./routeComponents";
import { useUserStore } from "@/stores/user";
import { arrayToTree } from "@/utils/util";
import { capitalize } from "lodash";
import type { RouteRecordRaw, Router } from "vue-router";
import defaultRoutes from './defaultRoutes'
import type { TMenuInfo } from "@/typing/base";

const whitelist = [ '/login', '/install' ] // 允许进入的页面路由配置


// 将后端返回的 导航配置 转换成功 vue-router 配置
export const handleRouteItem = (children: any, isChild = false) => {
  return children.map((item: any, index: number) => {
    const newItem: RouteRecordRaw = {
      path: item.path || '/' + index,
      name: item.name,
      meta: {
        Icon: item.icon,
        isChild: isChild
      },
      children: [],
    }
    // 说明是子路由
    if (item.pid) {
      newItem.component = item?.component
    }
    if (item?.children) {
      newItem.children = handleRouteItem(item.children, true)
    }
    return newItem
  })
}

// 后端返回的组件添加组件数据
const addComponent = (routes: TMenuInfo[]) => {
  return routes.map(item => {
    // /config/email => /Config/Email
    const comTplPath = item.path?.split('/').map((x: string) => {
      if (x !== '/') {
        return capitalize(x)
      }
      return x
    }).join('/');

    return {
      ...item,
      component: componentMap[comTplPath] || componentMap["/404"],
    }
  })
}

export const useRouterGuard = (router: Router) => {
  // 路由守卫
  let registerRouteFresh = true
  // 前置路由
  router.beforeEach((to, from, next) => {
    const hasToken = localStorage.getItem('token')
    if (whitelist.includes(to.path) || hasToken) {
      const userStore = useUserStore();
      const otherRoutes = userStore.menuData
      const otherRoutesData = addComponent(otherRoutes)
      const routesTree = arrayToTree(otherRoutesData)
      const routes = handleRouteItem(routesTree)
      // console.log('转换后的路由：', routes, )
      routes.forEach((route: RouteRecordRaw) => {
        router.addRoute(route)
      });
      // router.addRoute(routes)
      // 刷新页面，导航页面获取不到全部路由
      // 解决：将路由存储到store中，使用时从store中获取
      const allRoutes = [...defaultRoutes, ...routes]
      // && !item.meta?.isChild
      const asideRoutes = allRoutes.filter((item: RouteRecordRaw) => !item.meta?.hidden )
      // console.log('asideRoutes', asideRoutes)
      userStore.asideRoutes = asideRoutes

      // 如果首次或者刷新界面，next(...to, replace: true)会循环遍历路由，
      // 如果to找不到对应的路由那么他会再执行一次beforeEach((to, from, next))直到找到对应的路由，
      // 我们的问题在于页面刷新以后异步获取数据，直接执行next()感觉路由添加了但是在next()之后执行的，
      // 所以我们没法导航到相应的界面。这里使用变量registerRouteFresh变量做记录，直到找到相应的路由以后，
      // 把值设置为false然后走else执行next(),整个流程就走完了，路由也就添加完了。
      if (registerRouteFresh) {
        next({...to, replace: true})
        registerRouteFresh = false
      } else {
        next()
      }
    } else {
      next('/login')
    }
  })

  // 全局解析守卫
  router.beforeResolve(async (_to) => {});

  // 全局后置钩子
  router.afterEach((_to, _from) => {});
};
